/*
 * Copyright (C) Francisco Morero Peyrona. All rights reserved.
 *
 * This software is published under the terms of Open Source
 * License version 1.1, a copy of which has been included with this
 * distribution in the License.txt file.
 */

package jdbcmanager.swing.text;

import java.awt.*;
import javax.swing.text.*;

/**
 * Instructs its parent class to colorize SQL code. 
 * 
 * @author Francisco Morero Peyrona
 */
public class SQLStyledDocument extends CodeStyledDocument
{
   private final static String sTokenDelimiters       = " ;:{}()[]+-/%<=>!&|^~*\n\r\t";
   private final static String sSingleLineComment     = "--";
   private final static String sQuoteDelimiter        = "\'";
   private final static String sOpenMultiLineComment  = "/*";
   private final static String sCloseMultiLineComment = "*/";
   private final static String sEscape                = "\\";

   private       static SimpleAttributeSet sasComment  = null;
   private       static SimpleAttributeSet sasNormal   = null;
   private       static SimpleAttributeSet sasNumber   = null;
   private       static SimpleAttributeSet sasQuote    = null;
   private       static SimpleAttributeSet sasKeyword  = null;
   private       static SimpleAttributeSet sasFunction = null;
   
   //-------------------------------------------------------------------------//
   
   /**
    * Class constructor.
    */
   public SQLStyledDocument()
   {      
      initTokens();
   }
   
   /**
    * Add extra SQL keywords.
    * <p>
    * See <code>DatabaseMetadata.getSQLKeywords()</code>.
    * 
    * @param asKeyword
    */
   public void addExtraSQLKeywords( String[] asKeyword )
   {
      for( int n = 0; n < asKeyword.length; n++ )
         addKeyword( asKeyword[n].toLowerCase(), SQLStyledDocument.sasKeyword );
   }

   /**
    * Add prebuilt DBMS functions
    * 
    * @param asFunc
    */   
   public void addBuiltFunctionKeywords( String[] asFunc )
   {
      SimpleAttributeSet sas = getFunctionAttributeSet();   // Needs to be initialized: see the method
      
      for( int n = 0; n < asFunc.length; n++ )
         addKeyword( asFunc[n].toLowerCase(), sas );   // Must be in lower case
   }

   //-------------------------------------------------------------------------//
   
   /**
    * @see CodeStyledDocument#geCommentAttributeSet()
    */
   protected SimpleAttributeSet getCommentAttributeSet()
   {
      if( sasComment == null )
      {
          sasComment = new SimpleAttributeSet();
          
          StyleConstants.setFontFamily( sasComment, "Monospaced" );
          StyleConstants.setForeground( sasComment, Color.lightGray );
          StyleConstants.setItalic(     sasComment, true );
      }
      
      return sasComment;
   }

   /**
    * @see CodeStyledDocument#getNormalAttributeSet()
    */
   protected SimpleAttributeSet getNormalAttributeSet()
   {
      if( sasNormal == null )
      {
         sasNormal = new SimpleAttributeSet();
         
         StyleConstants.setFontFamily( sasNormal, "Monospaced" );
         StyleConstants.setForeground( sasNormal, Color.black );
      }
      return sasNormal;
   }

   /**
    * @see CodeStyledDocument#getNumberAttributeSet()
    */
   protected SimpleAttributeSet getNumberAttributeSet()
   {
      if( sasNumber == null )
      {
         sasNumber = new SimpleAttributeSet();
         
         StyleConstants.setFontFamily( sasNumber, "Monospaced" );
         StyleConstants.setForeground( sasNumber, Color.red.darker() );
      }
      
      return sasNumber;
   }

   /**
    * @see CodeStyledDocument#getQuoteAttributeSet()
    */
   protected SimpleAttributeSet getQuoteAttributeSet()
   {
      if( sasQuote == null )
      {
         sasQuote = new SimpleAttributeSet();
         
         StyleConstants.setFontFamily( sasQuote, "Monospaced" );
         StyleConstants.setForeground( sasQuote, Color.green.darker().darker() );
      }
      
      return sasQuote;
   }
   
   
   protected SimpleAttributeSet getFunctionAttributeSet()
   {
      if( sasFunction == null )
      {
         sasFunction = new SimpleAttributeSet();
         
         StyleConstants.setFontFamily( sasFunction, "Monospaced" );
         StyleConstants.setForeground( sasFunction, Color.cyan.darker().darker() );
      }
      
      return sasFunction;
   }

   /**
    * @see CodeStyledDocument#getQuoteDelimiter()
    */
   protected String getQuoteDelimiters()
   {
      return sQuoteDelimiter;
   }

   /**
    * @see CodeStyledDocument#getSingleLineComment()
    */
   protected String getSingleLineComment()
   {
      return sSingleLineComment;
   }
   
   /**
    * @see CodeStyledDocument#getOpenMultiLineComment()
    */   
   protected String getOpenMultiLineComment()
   {
      return sOpenMultiLineComment;
   }
   
   /**
    * @see CodeStyledDocument#getCloseMultiLineComment()
    */
   protected String getCloseMultiLineComment()
   {
      return sCloseMultiLineComment;
   }

   /**
    * @see CodeStyledDocument#getTokenDelimiters()
    */
   protected String getTokenDelimiters()
   {
      return sTokenDelimiters;
   }

   /**
    * @see CodeStyledDocument#getEscapeString()
    */   
   protected String getEscapeString( String sQuoteDelimiter )
   {
      return sEscape + sQuoteDelimiter;
   }

   //-------------------------------------------------------------------------//
   
    private void initTokens()
    {       
       String[] asSQL = { "select","from","where","between","like","distinct","order","by","asc","desc",
                          "count","join","left","right","inner","outer","insert","into","values","update",
                          "set","delete","create","table","alter","add","drop","column","index","unique","on" };
                           
       SQLStyledDocument.sasKeyword = new SimpleAttributeSet();
          StyleConstants.setFontFamily( sasKeyword, "Monospaced" );
          StyleConstants.setBold(       sasKeyword, true );
          StyleConstants.setForeground( sasKeyword, Color.blue.darker() );
         
       for( int n = 0; n < asSQL.length; n++ )
          addKeyword( asSQL[n], sasKeyword );
         
       SimpleAttributeSet sasLogicalOperator = new SimpleAttributeSet();
          StyleConstants.setFontFamily( sasLogicalOperator, "Monospaced" );
          StyleConstants.setBold(       sasLogicalOperator, true );
          StyleConstants.setForeground( sasLogicalOperator, Color.magenta.darker() );
      
       addKeyword( "and", sasLogicalOperator );
       addKeyword( "or" , sasLogicalOperator );
       addKeyword( "not", sasLogicalOperator );
    }
}